import random
import re

import logging
from flask import Blueprint, jsonify
from flask import current_app
from flask import g
from flask import make_response
from flask import request
from flask import session

from api_v1.my_decorators import is_login
from manager import redis_store, db
from models import User
from response_code import RET
from utils.captcha import captcha
from utils.qiniu_sdk import put_qiniu

user_blueprint = Blueprint('user', __name__, url_prefix="/api/v1/user")


# 图片验证码
@user_blueprint.route('/yzm', methods=['GET'])
def image_yzm():
    # 1.调用图片生成器方法生成图片验证码
    name, text, image = captcha.captcha.generate_captcha()
    # 打印图片验证码
    print(text)
    # 把图片验证码保存到session中方便判断
    session['image_yzm'] = text
    # 返回图片
    response = make_response(image)
    # 设置图片的储存类型
    response.headers['Content-Type'] = 'image/jpeg'
    # 返回响应
    return response


# 短信验证码
@user_blueprint.route('/send_sms', methods=["GET"])
def sms_code():
    # 1.获取参数
    mobile = request.args.get("mobile")
    imagecode = request.args.get("imageCode")

    # 校验参数
    #  1. 为空校验
    if not all([mobile, imagecode]):
        return jsonify(code=RET.PARAMERR, msg="参数不全")
    # 2 手机号码格式校验
    if not re.match(r"1[3-9]\d{9}$", mobile):
        return jsonify(code=RET.PARAMERR, msg="手机格式错误")

    # 图片验证码正确校验
    redis_image_code = session.get("image_yzm")
    # 图片验证码不存在
    if not redis_image_code:
        return jsonify(code=RET.NODATA, msg="图片验证码已过期")

    session.pop("image_yzm", None)

    if imagecode.lower() != redis_image_code.lower():
        return jsonify(code=RET.PWDERR, msg="图片验证码错误")
    # 生成随机短信验证码
    sms_code = "%06d" % random.randint(0, 999999)
    current_app.logger.debug(sms_code)
    print(sms_code)
    # 调用云通讯发送
    # ccp = CCP()
    # result = ccp.send_template_sms(mobile,[sms_code,5],1)
    #
    # if result == -1:
    #     return jsonify(errno=RET.THIRDERR,errmsg="云通讯发送失败")
    redis_store.set("sms_code:%s" % mobile, sms_code, 300)

    return jsonify(code=RET.OK, msg="发送成功")


# 注册
@user_blueprint.route('/user_register', methods=['POST'])
def user_register():
    # 1, 获取参数
    # 获取mobile,imagecode,phonecode,password,password2
    mobile = request.form.get("mobile")
    image_code = request.form.get("imagecode")
    phone_code = request.form.get("phonecode")  # 短信验证码
    password = request.form.get("password")
    password2 = request.form.get("password2")

    # 校验参数
    if not all([mobile, image_code, phone_code, password, password2]):
        return jsonify(code=RET.PARAMERR, msg="输入框不能为空")

    # 查询当前用户是否已经注册
    try:
        count = User.query.filter(User.phone == mobile).count()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.DBERR, msg="查询注册用户失败")

    # 判断用户是否已经注册
    if count > 0:
        return jsonify(code=RET.DATAEXIST, msg="用户已注册")

    # 判断短信验证码的正确性
    redis_phonecode = redis_store.get("sms_code:{}".format(mobile))

    # 判断缓存中是否存在短信验证码
    if not redis_phonecode:
        return jsonify(code=RET.DBERR, msg="短信验证码查询失败")

    # 判断用户输入验证码是否与缓存验证码匹配
    if redis_phonecode != phone_code:
        return jsonify(code=RET.PARAMERR, msg="短信验证码错误")

    # 判断密码是否符合规则
    if not re.match(r'[a-zA-Z][0-9a-zA-Z]{5,15}$', password):
        return jsonify(code=RET.PWDERR, msg="密码格式错误")

    # 判断两次密码是否一致
    if password != password2:
        return jsonify(code=RET.PWDERR, msg="两次密码不一致")

    # 注册用户数据入库
    try:
        user = User()
        user.phone = mobile
        user.password = password

        # 添加到数据库并提交
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        jsonify(code=RET.DATAERR, msg="入库失败")

    return jsonify(code=RET.OK, msg="注册成功")

# # 修改个人信息
@user_blueprint.route("/", methods=["get", "PUT"])
@is_login
def base_user():
    if request.method == "GET":

        # 1,判断是否为当前用户登录
        if not g.user:
            return jsonify(code=RET.LOGINERR, msg="用户登录异常")

        # 3,1 查询当前用户是否与数据库的用户匹配
        try:
            user = User.query.get(g.user.id)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(code=RET.DBERR, msg="查询用户失败")

        # 3,2 判断用户是否存在
        if not user:
            return jsonify(code=RET.USERERR, msg="用户不存在")

        # 响应成功
        return jsonify(code=RET.OK, msg="用户信息显示成功", user=user.to_basic_dict())

    # 1.判断用户是否登陆
    if not g.user:
        return jsonify(code=RET.SESSIONERR, msg="用户未登陆")
    # if request.method == "GET":
    #     name =request.args.get("name")
    #     avatar =request.args.get("avatar")
    #     try:
    #         name = User.query.filter(User.name==name).first()
    #     except Exception as e:
    #         return jsonify(code=RET.DBERR,msg="查询失败")
    #     try:
    #         avatar = User.query.filter(User.avatar == avatar).first()
    #     except Exception as e:
    #         return jsonify(code=RET.DBERR, msg="查询失败")
    #     data={
    #         "name":name,
    #         "avatar":avatar
    #     }
    #     return jsonify(code=RET.OK,data=data)

    # 2.获取参数
    data_dict = request.form
    print(data_dict)
    if 'name' in data_dict:

        name = request.form.get("name")
        if not name:
            return jsonify(code=RET.PARAMERR, msg="参数不全")
        g.user.name = name

        g.user.add_update()
        return jsonify(code=RET.OK, msg="修改名字成功")
    elif 'avatar1' in data_dict:
        avatar = request.files.get("avatar")

        # 3.校验参数
        if not all([avatar]):
            return jsonify(code=RET.NODATA, msg="参数不全")
        # 4.上传七牛云
        try:
            img_url = put_qiniu(avatar)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(code=RET.NODATA, msg="七牛云异常")
        if not img_url:
            return jsonify(code=RET.NODATA, msg="没有这个图片")

        # 5 .修改数据库数据
        g.user.avatar = img_url
        g.user.add_update()
        return jsonify(code=RET.OK, msg="修改头像成功", url=current_app.config['QINIU_URL'] + img_url)
    elif "old_pwd" in data_dict:
        # 1.获取参数
        old_password = request.form.get("old_pwd")
        new_password = request.form.get("new_pwd")
        new_password2 = request.form.get("new_pwd2")
        # 2.校验参数
        if not all([old_password, new_password, new_password2]):
            return jsonify(code=RET.PARAMERR, msg="参数不全")
        if new_password != new_password2:
            return jsonify(code=RET.DATAERR, msg="两次新密码不一致")
        # 3.校验密码
        if not g.user.check_pwd(old_password):
            return jsonify(code=RET.PWDERR, msg="旧密码错误")
        # 4.修改数据库
        g.user.password = new_password
        g.user.add_update()
        return jsonify(code=RET.OK, msg="success")
    else:
        return jsonify(code=RET.PARAMERR, msg="参数错误")

# 登陆视图
@user_blueprint.route('/session', methods=['get', 'POST', 'DELETE'])
@is_login
def user_login_logout():
    # 判断是否登陆
    if request.method == "GET":
        if g.user:
            return jsonify(code=RET.OK, name=g.user.name)
        else:
            return jsonify(code=RET.LOGINERR)

    # 退出登陆
    if request.method == "DELETE":
        session.pop("user_id", None)
        return jsonify(code=RET.OK, msg="退出成功")

    # 1 获取参数
    # data_dict = request.form
    mobile = request.form.get('mobile')
    password = request.form.get('password')

    # 2 验证参数
    if not all([mobile, password]):
        return jsonify(code=RET.PARAMERR, msg="参数不全")

    # 3 查询用户
    user = None
    try:
        user = User.query.filter(User.phone == mobile).first()
    except Exception as e:
        logging.error('用户登录-----数据库出错')
        return jsonify(code=RET.DATAERR, msg="登陆失败")

    # 4 判断用户是否存在
    if not user:
        return jsonify(code=RET.PARAMERR, msg='用户不存在')

    # 判断密码是否正确
    if not user.check_pwd(password):
        logging.error("密码错误")
        return jsonify(code=RET.PARAMERR, msg='密码不正确')

    # 在sessino中保存用的登录信息
    session['user_id'] = user.id
    return jsonify(code=RET.OK, msg='OK')


# 实名验证
@user_blueprint.route('/auth', methods=['PUT', 'GET'])
@is_login
def user_auth_set():
    '用户实名认证'
    # 判断用户的登陆方式
    if g.user and request.method == 'GET':
        user = g.user
        return jsonify(user.to_auth_dict())

    # 1.获取参数
    dict_data = request.form
    id_name = dict_data.get('id_name')
    id_card = dict_data.get('id_card')
    user = g.user

    # 2.验证参数
    # 为空校验
    if not all([id_name, id_card]):
        return jsonify(code=RET.PARAMERR, msg='获取失败')
    # 验证身份号
    if not re.match(r'^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$', id_card):
        return jsonify(code=RET.PARAMERR, msg='身份证格式有误')

    # 验证身份证是否绑定过
    try:

        if User.query.filter(User.id_card == id_card).first():
            return jsonify(code=RET.DATAEXIST, msg='身份证已存在')
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.DATAEXIST, msg='查询身份证错误')
    # 3.数据入库
    try:
        user.id_name = id_name
        user.id_card = id_card
        user.add_update()

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(code=RET.DBERR, msg='保存失败')
    # 4.返回响应
    return jsonify(code=RET.OK, msg='成功', data={'id_name': id_name})
